package com.test.webscoket.main;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.net.ServerSocket;
import java.util.Map;
import java.util.Set;

@Service
@Slf4j
@ServerEndpoint("/ws/{deptId}/{userPid}")
public class WebSocketServer {

    private Session session;
    private String deptId;
    private String userPid;
    private String sessionKey;

    @Autowired
    private Environment env = SpringUtil.getBean(Environment.class);

    @Autowired
    private RedisSessionManager redisSessionManager = SpringUtil.getBean(RedisSessionManager.class);

    @Autowired
    private WebSocketSessionManager webSocketSessionManager = SpringUtil.getBean(WebSocketSessionManager.class);

    @Autowired
    private RedisMessageSender redisMessageSender = SpringUtil.getBean(RedisMessageSender.class);
//    @Resource
//    private RedisUtil redisUtil = SpringUtil.getBean(RedisUtil.class);

    // 获取当前服务端口
    private String getServerId() {
        String port = env.getProperty("local.server.port");
        return "server-"+port;
    }

    // 检查是否是当前服务器
    private boolean isCurrentServer(String serverId) {
        return getServerId().equals(serverId); // 假设当前服务器 ID 为 server1
    }

    /**
     * 建立连接
     * @param session
     * @param userPid
     */
    @OnOpen
    public void onOpen(Session session,@PathParam("deptId") String deptId, @PathParam("userPid") String userPid) {
        this.session = session;
        this.deptId = deptId;
        this.userPid = userPid;
        this.sessionKey = deptId+"_"+userPid;
        String serverId = getServerId();

        // 如果是当前服务器，则通知其他服务器断开连接
        Map<String, String> sessionInfo = redisSessionManager.getSession(sessionKey);
        if (CollectionUtil.isNotEmpty(sessionInfo)){
            redisMessageSender.sendMessageToClient(sessionKey, "unRegister");
        }
//        if (isCurrentServer(serverId)) {
//            redisMessageSender.sendMessageToClient(sessionKey, "unRegister");
//        }
//        redisUtil.setHash(sessionKey, "clientId", sessionKey);
//        redisUtil.setHash(sessionKey, "serverId", serverId);
        // redis存储会话信息
        redisSessionManager.storeSession(sessionKey, serverId);
        // 本地存储会话信息
        webSocketSessionManager.addSession(sessionKey, session);
        // 获取所有会话信息
        Set<String> allSessions = redisSessionManager.getAllSessions(deptId);
        log.info("[连接ID:{}] 建立连接,连接数:[{}]", this.sessionKey,allSessions.size());
    }

    /**
     * 断开连接
     */
    @OnClose
    public void onClose() {
        // 删除redis会话信息
        redisSessionManager.deleteSession(sessionKey);
        // 删除本地会话信息
        webSocketSessionManager.removeSession(sessionKey);
        // 获取所有回话信息
        Set<String> allSessions = redisSessionManager.getAllSessions(deptId);
        log.info("[连接ID:{}] 断开连接,连接数:[{}]", this.sessionKey,allSessions.size());
    }

    /**
     * 发送错误
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.info("[连接ID:{}] 错误原因:{}", this.sessionKey, error.getMessage());
        error.printStackTrace();
    }

    /**
     * 收到消息
     * @param message
     */
    @OnMessage
    public void onMessage(String message,@PathParam("deptId") String deptId) {
        log.info("[连接ID:{}] 收到消息:{}", this.sessionKey, message);
        // 获取所有会话信息
        Set<String> allSessions = redisSessionManager.getAllSessions(deptId);
        try {
            for (String key : allSessions) {
                if (key.startsWith(deptId.substring(0,8))){
                    Map<String, String> sessionInfo = redisSessionManager.getSession(key);
                    // 如果是当前服务器，则发送信息
                    if (isCurrentServer(sessionInfo.get("serverId"))){
                        webSocketSessionManager.sendMessageToClient(key, message);
                    } // 如果不是当前服务器，则通过redis发布到其他服务器
                    else {
                        redisMessageSender.sendMessageToClient(key, "message:"+message);
                    }
                }
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 群发消息
     * @param message
     */
//    public void sendMassMessage(String message,String deptId,String userPid) {
//        try {
//            for (String key : webSocketMap.keySet()) {
//                if (key.startsWith(deptId)){
//                    if (StrUtil.isNotBlank(userPid)){
//                        if (key.endsWith(userPid)){
//                            WebSocketServer wsServer = webSocketMap.get(key);
//                            Session wsSession =  wsServer.session;
//                            wsSession.getBasicRemote().sendText(message);
//                            log.info("[连接ID:{}] 发送消息:{}",key,message);
//                            break;
//                        }
//                    } else {
//                        WebSocketServer wsServer = webSocketMap.get(key);
//                        Session wsSession =  wsServer.session;
//                        wsSession.getBasicRemote().sendText(message);
//                        String token = wsSession.getRequestParameterMap().get("access_token").get(0);
//                        log.info("[连接ID:{},token:{}] 发送消息:{}",key,wsSession.getRequestParameterMap().get("access_token"),message);
////                    wsServer.session.close();
//                    }
//
//                }
//            }
//        } catch (IOException e) {
//            throw new RuntimeException(e);
//        }
//    }



}
